package info.hexin.redis.springdata;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

/**
 *  这个可以支持 几乎可以支持任意序列化，包括放进去的时候和去出来的属性的个数不一致。 但是不能修改属性的值
 * Created by infi.he on 2016/1/28.
 */
public class KryoRedisSerializer1<T> implements RedisSerializer<T> {
    @Override
    public byte[] serialize(Object t) throws SerializationException {
        Kryo kryo = new Kryo();
        Output output = null;
        try {
            kryo.setDefaultSerializer(CompatibleFieldSerializer.class);
            kryo.setReferences(false);
            kryo.setRegistrationRequired(false);
            output = new Output(1024 * 1024, -1);
            kryo.writeClassAndObject(output, t);
            output.flush();
            return output.toBytes();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (null != output) {
                output.close();
                output = null;
            }
        }
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        Kryo kryo = new Kryo();
        kryo.setDefaultSerializer(CompatibleFieldSerializer.class);
        kryo.setReferences(false);
        kryo.setRegistrationRequired(false);
        if (bytes == null) {
            return null;
        }
        Input input = null;
        try {
            input = new Input(bytes);
            T t = (T) kryo.readClassAndObject(input);
            return t;
        } finally {
            if (input != null) {
                input.close();
                input = null;
            }
        }
    }
}
